[NOTE: This is the text file taken from issues of _Possibilities_. It is quite old and there have been many additions to the System Definition Language (SDL). Please note that any page number references are probably no longer valid. Also I left in the old-fashioned"typewriter-style" 2-space punctuation. That being stated, it is an excellent introduction to SDL. SDL is probably easier to learn and use than a main BBS .BATch file and infinitely faster than MEDIT. One of the things that you might try: after using this introduction, you may well find that using numerous MENUXXXX.SDL files much faster and more convenient than using a single one. Using a text editor, such as Q-Edit, will - with the addition of DOSKEY (included with DOS v5 and later) - make editing and compiling .SDLfiles smooth and close to effortless. Enjoy!! Gray Shockley / Board on Boards BBS / postmaster@compcomm.com ] ----------------------------------------------------------------------------------------- An SDL Primer by Alan Bechtold Copyright 1990 by eSoft, Incorporated. All Rights Reserved ----------------------------------------------------------------------------------------- Note: The following four part series on using SDL is reprinted with permission from the eSoft possibilities newsletter. Possibilities is a monthly customer support publication of: eSoft, Incorporated 15200 E. Girard Avenue Suite 2550 Aurora, Co 80014 This series of articles may not be reproduced in any form except by inclusion of the above copyright notice. This file is authorized for distribution without charge only if it is unchanged in any way. Any use of this information in any other way must include proper credit to its source. Part 1: Getting started with SDL The idea of a "computer language" conjures up images of all-night sessions in front of a terminal -- struggling to master a complex new way to talk to your computer. SDL -- the TBBS System Definition Language Compiler -- isn't that way at all. SDL is just a different way to design and maintain all of your TBBS system's menus. SDL's approach to TBBS menu construction and maintenance is easy to learn. With SDL, you use your favorite word processor or text editor to write out all of your TBBS menus in an ASCII text file. It's like writing a letter, but you have to learn to write it in terms that the SDL compiler will understand, so it can follow your instructions and build the TBBS menus you want. The first step is to understand how the SDL compiler works. The SDL compiler reads your SDL source file (the ASCII text file I mentioned above) and, like a duti- ful French chef, follows your commands, creating TBBS menus exactly as you've specified. Because you may already have menus you built with MEDIT, the SDL decompiler is also provided. The SDL decompiler takes TBBS menus that already exist on your system and creates an SDL source file for your system. This allows you to start using SDL whenever you're ready. You can start with the MEDIT menus you've got now, without worrying about re-doing anything you've already done on your system. Since most TBBS system designers start with MEDIT and already have at least a few TBBS menus they're using on their systems, let's start by getting familiar with the SDL decompiler. Pick one of your menu files -- a simple one would be best to start with -- and we'll decompile it together. Since I don't have any way to know which existing menu you've selected to decompile I'll use your top level menu -- MENU0000.CTL -- in the following examples. Make sure the program SDLDC.COM is in the same subdirectory as the menu file, then type: SDLDC SAMPLE /M:0000 The "/M:0000" on the the end of the above command is an option that tells SDLDC to decompile only the single menu file named after the "/M:". Typing the above command will decompile the menu file MENU0000.CTL, and create an ASCII text file named SAMPLE.SDL. This is the SDL source file that is your menu written in SDL format. You can look at it with any word processor or text editor. In fact, go ahead -- use your word processor to look at SAMPLE.SDL. Then look at the your MENU0000.CTL file with MEDIT (the original menu file itself isn't changed or destroyed by SDLDC.COM). You'll definitely gain some insight into the way SDL works. For example, the ASCII text SDL source file for a simple menu to read messages on your system might look like this: Menu:0000 Billing:7 Title: READ TBBS MESSAGES ------------------ EndTitle: Entry: ead Messages A1=--X----- Key=R Type=6 Opt Data=Bulletin Board . . . EndMenu: The first line in the above example -- Menu: 0000 -- tells the SDL compiler that all text that follows, until the line reading EndMenu: is reached contains the specifications for a single TBBS menu named 0000. Billing:7, the next line, indicates that the above menu will accrue time against the user's account in Billing Class 7, as specified in ULEDIT by the TBBS system designer. If this line is absent, the menu is assigned to Billing Class 0 by default. Next comes the line that reads Title:. This command -- like the Menu: and EndMenu: commands -- tells the SDL compiler that the text which follows -- until the line that reads EndTitle: is reached -- will be displayed as the title of the specified menu. The Entry: command specifies the various options offered to the user on this particular menu. The specifications that follow the Entry: command ("A1=" "Key=" "Type=6" and "Opt Data=Bulletin Board"), indicate the A1 flags that must be set for the user to access this specific menu option, the key that will activate the option, the option's TBBS Type (in this case, the Receive Messages option), and the Opt Data that must be specified for that menu option. These serve the same functions as their counterparts in MEDIT. You should see by now that the text in an SDL source file is very much like the layout of a menu when you look at it with MEDIT. That's because SDL was designed to extend and broaden MEDIT, to replace it totally. If you wish, you can also decompile all the menus on your TBBS system into a single ASCII SDL source file. To do this, just type: SDLDC SAMPLE If you leave OFF the optional /M: argument that was included in our first step, SDLDC will decompile every menu in your system into the single source file you've named. This file will contain all of your TBBS system's menus, in easy-to-modify ASCII text, and will afford you a complete overview of your system at all times. It also allows you to use all the powerful features your favorite word processor or text editor has to offer modifying and updating your system's menus. Control codes can also be entered in SDL source files, so you can build menus incorporating ANSI or IBM graphics. Now it's time to compile the menu(s) we just decompiled. Make sure the program SDL.COM is in the same subdirectory as SAMPLE.SDL. Then, type: SDL SAMPLE and the SDL compiler will compile the ASCII text file, SAMPLE.SDL, that was created when you decompiled the menu(s) from your own system, back into .CTL file form. This new .CTL file would include any changes we made to the source file with your text editor -- if we had made any. Because you can define all of your system's menus in a single ASCII .SDL text file, you can also instruct SDL to compile only a single menu from an .SDL file. You do this by following the above command with a slash, "M:" and the name of the single menu you want compiled. In our example, you'd type: SDL SAMPLE /M:0000 to instruct the SDL compiler to compile only the MENU0000.CTL menu file from SAMPLE.SDL, even if it contained source code for all of your system's menus. This option allows you to keep your entire system's menu definitions in a single source file, but still makes it easy to make changes to individual menus. To see how SDL works with your entire system, type the following: SDLDC SAMPLE This will make SDLDC decompile ALL the menus on your TBBS system into a single SDL source file, named SAMPLE.SDL. When the compiler's through, load up your favorite word processor again and take a look at SAMPLE.SDL. This time you'll see every menu in your TBBS system, written out in SDL source code, ready to modify, change, or compile again. Now, let's compile only the menu from your system that we decompiled as our first step in this tutorial. To do this, type: SDL SAMPLE /M:0000 You will see that SDL only compiles and replaces MENU0000.CTL even though the SAMPLE.SDL file contains all of the menus in your system. There are two more options you can use when you run the SDL compiler: LISTING and / T. SDL's LISTING option creates a fully expanded ASCII text file of a specified single menu or of your entire system, with all the macros you used in your original SDL source file fully expanded. This is useful when you begin defining Macros in your SDL source. SDL Macros are just like the macros used in many applications programs or with DOS. They allow you to specify groups of commands, even entire menus, with a single keyword. We'll discuss SDL Macros -- and the LISTING option -- in part three of this tutorial series. The / T option will perform a test compile of any single menu or of your entire system. SDL will compile the menus you specify, but doesn't actually write any .CTL files as a result. This is useful when you want to test to make sure you've written your SDL source code correctly. If you've made any errors in your SDL source code, a quick test compile with SDL and the / T option will notify you of them with an error message. Next issue, we'll examine the syntax of TBBS's System Definition Language -- the way to actually phrase your SDL commands so the compiler will understand them. Until then, practice using the SDL compiler. Try decompiling your menus. Use MEDIT to examine each .CTL file and your word processor to examine the ASCII SDL source file closely. As an added exercise, copy one of your menu .CTL files to a file with a new name (keeping the .CTL extension), so you have a menu file you can play with. Use MEDIT to change something in the new menu file you've created, then decompile the changed menu to SDL. See if you can spot the changes by looking at the resulting .SDL source file with your text editor. Then, use your text editor to try and change the menu BACK the way it was. Compile the changed menu with SDL and see how the new .CTL file looks with MEDIT. Try these exercises a few times and you'll not only be ready for the next part, you'll be ahead of the rest of the class. See you then. Part 2: Building Menus ---------------------- The TBBS System Definition Language Compiler (SDL), is easier than it looks. Simply put, it's just a different approach to designing and maintaining all of your TBBS system's menus. Although you don't have to give up the comfortable menu-driven MEDIT program completely, you probably will -- after you start getting the drift of SDL -- because SDL is a complete replacement for MEDIT in every way. In our first installment in this series, we examined the SDL compiler and decompiler and actually put both to work. Now, as promised, we're going to look closely at the language itself. The TBBS System Definition Language is written using a variety of commands. These commands are written, usually one per line, in ASCII text files, called SDL source files. SDL source files are written and modified using any word processor or text editor capable of creating and editing ASCII text. Within any SDL source file, menus are defined in two basic parts: Macro Definition and Menu Definition. We'll deal with Macros and how they work within your SDL source code in the next installment of this series. Each menu definition in an SDL source code listing is begun with the "Menu:" Directive, followed by the name of the menu that's being defined. A Menu Definition section is ended with the "EndMenu:" Directive. Everything between the "Menu:" and "EndMenu:" Directives defines the menu named in the "Menu:" opening Directive. Menu titles are written between the "Title:" Directive and the "EndTitle:" directive. Each of these Directives is typed on a line by itself and everything typed on the lines between them will appear as the title of a TBBS menu on your system when the SDL source file is compiled. Let's take another look at the sample menu we worked with in the last installment of this series: Menu:1000 Billing:7 Title: READ TBBS MESSAGES ------------------ EndTitle: Entry: ead Messages A1=--X----- Key=R Type=6 Opt Data=Bulletin Board ... EndMenu: You should now be able to see that this menu definition will create a .CTL file named MENU1000.CTL. The menu's title, as it will appear on the compiled TBBS system, will be "READ TBBS MESSAGES". Another menu could be started, in the above SDL source listing, by typing "Menu:" and a different menu's name on a single line following the "EndMenu:" directive. If you've done any work with MEDIT at all, it's fairly easy to see that SDL makes the simple task of writing out a menu's title even easier. And it gets better. The "Billing:" Directive follows the "Menu:" Directive in the above example. This assigns a TBBS Billing Class to the menu that's being defined. If you don't specify a Billing Class in your menu, it will default to a Billing Class of 0. For a complete discussion of TBBS Billing classes and how they work, see pages 2-14 through 2-16 in the TBBS manual. Now you know how to start and stop, assign a billing class and create a title for each of your menus with SDL. The next step is to set up each of your menu's options. This is done with the "Entry:" block Directive. The "Entry:" block is usually entered following the "EndTitle" Directive. Keywords following an "Entry:" Directive define each option that will be offered on the menu being defined. In your SDL source file, you just write "Entry:" (without the quotes) on a line by itself to start an "Entry:" block. In the sample menu above, there are five lines of text following the "Entry:" Directive. These will set up one menu entry line that will be seen by a user with his or her A1 flag set to "--X-----". It's a Type 6 menu option (Retrieve Messages) and will be activated when the user presses an "R." In this case, theuser will be presented with messages that have been posted on the BULLETIN BOARD message base, as specified in the "OPT DATA=Bulletin Board" statement. Be sure to examine the sample menu above carefully as you read through the above paragraph. Notice, for example, that only the A1 flags are defined. The above "Entry:" block could also have included definitions for the A2, A3 and A4 flags. They were omitted in the above example because only the A1 flag was important to that menu option. Any time you don't define a flag setting in the text following an "Entry:" Directive, SDL assumes those flags to be "--------". Remember that each "Entry:" block is ended by the next Directive (which could be another "Entry:" Directive) or by the "EndMenu:" directive. As I pointed out earlier, SDL works very much like MEDIT. The main difference is that SDL lets you do everything in a text file, with your favorite word processor. Believe it or not we've already covered everything you need to start writing SDL source files of your own. One other Directive -- "Include:" -- is discussed when we examine Advanced SDL issues, in a later chapter. Before we start writing SDL source code, however, we need to review some of the principals of the language's syntax. Keep the following points in mind and your SDL source files will compile with the least number of errors possible: STRUCTURE --------- As we've already discussed, SDL source files are basically divided into sections of two distinct types: Macro Definition and Menu Definition. Each of these sections is delimited by a beginning and ending Directive. Thus, each Macro Definition begins with "Macro:MacroName" and ends with "EndMacro." Each Menu Definition begins with "Menu:MenuName" and ends with "EndMenu." There is one exception to this rule. When you start a new section of the same type as the previous one, you don't need to end each section with the "End:" Directive. For example, when you're defining several menus within your SDL source file, you would start each menu with an appropriate "Menu:MenuName" Directive, but you only have to include an "EndMenu" directive on the last menu definition in the chain. It goes something like this: Menu:1000 . . Body of Menu 1000 . Menu:2000 . . Body of Menu 2000 . Menu:3000 . . Body of Menu 3000 . EndMenu: DIRECTIVES ---------- As we've discovered, these are the heart and soul of any SDL source file. When writing Directives into your SDL source file, remember that they must always begin with the first non-blank character of a line. Directives also cannot contain any embedded blanks and they must always end with a colon. They can include an argument (such as a menu name on the "Menu:" Directive line, or the name of a macro on the "Macro:" Directive line), but anything past the argument (or past the Directive, if there is no argument) will be treated as a comment to the end of the line and will be ignored by SDL when compiling your source file into menus. KEYWORDS -------- Keywords are used to specify arguments, which can be either Numeric, Flag settings or Text. Keywords are always ended with an equal sign and are followed by the keyword's argument. You can place keywords and arguments several to a line if you wish, or you may give each a line of its own. Arguments are always ended with one or more spaces or the end of a line. In the sample source above, the keywords are "A1=" "Key=" "Type=" and "Opt Data=". The text following each is that keyword's argument. They could just as easily have been written out like this: A1=--X----- Key=R Type=6 Opt Data=Bulletin Board The one EXCEPTION to the above rules is "Opt Data=". SDL will consider ALL the text that follows this keyword as a text parameter, to the end of the line. This means that the "Opt Data=" keyword must be the last entry on a line. UPPER AND LOWER CASE -------------------- Except for the text you enter between a "Title:" and "EndTitle:" Directive, upper and lower case are not considered unique by SDL. You are perfectly free to use capitalization in your SDL code in any way that will make it easier for you to follow. SPACES AND WHITE SPACE ---------------------- You may indent your SDL source files any way you wish. Whatever makes them easier for you to read. The one exception to this is text between the "Title:" and "EndTitle:" Directives. Any text appearing between these two Directives will display on your menu exactly as it was written in the source file. Everywhere else, however, SDL considers any number of spaces as a single space, and will thus ignore the spacing you used when writing it. CONTROL CHARACTERS ------------------ To indicate to SDL that you want a control character to become part of a menu when your source file is processed, it must be preceded by a "^" (without the quotes). Thus, "control A" would be entered in your source code file as "^A" (without the quotes). Of course, this means the "^" character is special in SDL. If you wish to use it by itself, so it will display on a menu's title, for example, you must enter it twice ("^^") in your SDL source file. This tells SDL "I really want a "^" to appear here -- NOT a control character." A list ofthe 32 control characters and what they are appears on page 7-4 in your TBBS manual. COMMENTS -------- It's always nice to add comments to your SDL source files, to remind you of why you did certain things, and to let other people who may have to use your SDL source files know what's going on. Comments in SDL are simple: just start a line with a semi-colon (;) and anything that follows it on the rest of the line will be ignored. Needless to say, you can't enter comments inside of a "Title" or "Entry" text block or they will appear as part of your TBBS menu. ; This could be a comment in your SDL ; file. If you need more than one line ; just keep using semi-colons and text Longer comments can be placed between a "Remark:" and its corresponding "EndRemark:" Directive. This is indeed another SDL Directive, but its sole purpose is to allow you to include blocks of text within your SDL source files. The "Remark:" Directive is used just like the "Title:" Directive. Proper use of comments and "Remark:" blocks within your SDL source files allows you to actually include documentation for your source files within the source itself. This can be a big help when you go back to modify your system later. You now have all the tools you need to create an entire TBBS system with SDL. Next issue, we'll look at adding POWER tools to your arsenal -- SDL's Macros and other advanced considerations. Until then, your assignment is to add two more options to the sample menu above. One should be "Write Messages" and the other should be "oodbye -- Log Off System". Make the "rite Messages" option available to users with their A1 flags set to "--X-----" and the "oodbye" option available to any caller. Try compiling the menu (be sure to copy the source file and SDL.COM and SDLDC.COM into a subdirectory OTHER than your current working TBBS subdirectory). Part 3: Using Macros -------------------- The TBBS System Definition Language Compiler (SDL), is easier than it looks. Simply put, it's just a different approach to designing and maintaining all of your TBBS system's menus. Although you don't have to give up the comfortable menu-driven MEDIT program completely, you probably will -- after you start getting the drift of SDL -- because SDL is a complete replacement for MEDIT in every way. In our first two installments we've covered all the basics you need to write working SDL source code and create menus. Now it's time to learn how to drastically cut down the time and effort you spend -- with SDL Macros. Macros can actually reduce cumbersome often-repeated source code to a few simple keystrokes. And they're surprisingly easy to create and use. What are MACROs? ---------------- SDL Macros are like abbreviations, but much more compressed. They're a TBBS menu designer's shorthand. If you run Lotus 1-2-3 or any one of the popular DOS macro programs, you're probably already familiar with the general concept of macros. SDL Macros are created by typing a Macro Directive into your SDL source code. The Macro Directive names and defines each of your Macros. You decide how many Macros you wish to use, what their names are and what they mean. Just think of SDL Macros as a way to customize SDL to your own liking by adding your own commands which can stand for any text you'd like. Once you've defined a series of macros, the text they represent is then included in your expanded source code listings (and in the menus that result from compiling your source code), placed wherever you've used the matching Macro Callouts in your SDL source code (we'll take a look at Macro Callouts in a minute). You can, for example, define a Macro to represent the authorization flag settings for one class of user on your system. Then, whenever you type the name of that Macro in your SDL code (the Macro Callout), that particular configuration of authorization flag settings will appear in your expanded source code listing and in the TBBS menu that results when you compile the complete SDL source code listing. The first step is to define the Macros you'll be using. This is done, anywhere within your SDL source code file, with the Macro: Directive. The Macro: Directive works like the Menu: Directive we learned about earlier. In your source code, type "Macro:" followed by the name you wish to assign to that particular Macro. For example, to create a Macro named "Users" you would type "Macro: Users" on one line. Then, on the lines following the Macro name, you would type the text that Macro will represent. Macro names can include any alphanumeric characters, including the special characters _ # $ and &, in any combination, up to 128 characters in length. The standard Macro Definition structure looks something like this: Macro: Users . . Body of Macro "Users" . Macro: MoreUsers . . Body of Macro "MoreUsers" . EndMacro: The body of your Macro is everything that appears between the "Macro: name" and the "EndMacro:" Directives. This is the actual text or menu definition information that will appear, wherever you place the appropriately named Macro Callout in your source code, in your compiled system menus and expanded SDL source code listings. Macro Callouts are simply an @ sign followed by the Macro's name. To call out our sample Macro, with the name Users, you would simply type: @Users anywhere in your SDL source code where you want the text you've defined with the Macro: Users Directive to appear. Macro Callouts can be included in any SDL source code text, including Text Definition blocks. This makes the @ character special. SDL will think you are calling out a Macro whenever the character appears in your text unless you type two @@'s in a row instead. This is the way you tell SDL that you want a single @ sign to be treated as text. Ordinarily, a single space between the end of your Macro Callout and the continuation of your text is enough to tell SDL where your macro name ends, but not always. For example, if a Macro, named UserDrive, was defined to replace the drive designator D:, it could be written like this: and would be called out like this: @UserDrive but, inside a string of text, you might run into a situation where you want to use the macro like this: Opt Data=@UserDrive \PATH\USERS Note the space following the @UserDrive callout above. This is necessary, to tell SDL that the Macro Callout has ended and the pathname, which is the continuation of your source code text, has begun. But, when SDL expands this Macro, as you compile your source code, you'll get an unwanted space between the resulting D: drive designator and the pathname, like this: OptData=D: \PATH\USERS In cases like this, just type a + sign at the end of your Macro Callout to tell SDL you've reached the end of the callout, without the extra space. For example: OptData=@UserDrive+\PATH\USERS would properly expand to: OptData=D:\PATH\USERS Ordinarily, the + sign isn't necessary at the end of Macro Callouts outside of text strings, but you can use this convention any time you wish. PARAMETER PASSING ----------------- If you want to reduce your keystrokes (and source code) even more, SDL's Macro Parameter Passing can be the answer. With Parameter Passing, you can specify up to nine arguments within your Macro Definition (with %1, %2, %3 and so on, through %9), then actually define each of those arguments in each Macro Callout, changing them with each Callout as you see fit. This sounds more complex than it really is. Actually, Parameter Passing is just a way to make selected Macros more flexible. For example, you COULD create the following different Macro definitions: Macro: Define1 Type=34 Key=D Opt Data=C:\FILES\DNLD Macro: Define2 Type=28 Key=F Opt Data=C:\FILES\UPLD EndMacro: These two Macros would be called out with the @DEFINE1 and @DEFINE2 callouts, respectively. This is a perfectly acceptable way to do it. But you could, instead, define this SINGLE Macro: Macro: Define Type=%1 Key=%2 Opt Data=%3 EndMacro: and call it out several different ways in your SDL source code. In the above example Macro, we've used three Parameters for the actual menu configuration data. The number of each Parameter tells SDL how to order the list of variable Parameters that you'll specify when you call out the above Macro in your SDL source code. For example, you could call out the SAME example Macro two different ways: @DEFINE(34,D,C:\FILES\DNLD) and @DEFINE(28,F,C:\FILES\UPLD) This would give you the same result as the two DIFFERENT Macro definitions and Macro Callouts in the preceding example. Notice that your arguments are stated within parenthesis, in the order in which you wish them to be placed. The parentheses always follow the Macro Callout, with no spaces between them and the Callout. You can include embedded and trailing spaces in your Macro Callout arguments. However, you must enclose your arguments within single or double quotes if you want to include leading spaces, commas or parenthesis as part of a Macro parameter. Arguments within Macro Parameters can be mixed any way you wish, as long as there are no more than the nine total that are allowed. You can also leave out arguments when calling out a Macro with parameters. When a Macro Callout with blank parameters is expanded, the missing arguments will be blank in your compiled menu and expanded source code listing. This capability can be useful for those TBBS menu options that automatically revert to default settings when left blank. Why type more than you have to? EQUATE DIRECTIVES ----------------- Another quick and easy way to use Macros within your SDL code is the Equate Directive. The Equate Directive works like a Macro and follows all of the rules of Macro definition, but it's defined on a single line. Equate Directives are especially handy if you want to define a single parametric value. For example: Equate: DataFiles = D:\TBBS\DATAFILE defines exactly the same macro as: Macro: DataFiles D:\TBBS\DATAFILE EndMacro: Equates are called out exactly the same way as you would call out any Macro. The Equate we defined in the above example could be called out like this: Opt Data=@DataFiles+\FILE1 This type of equate can be very useful if you move areas around on your disk drive. You need only change the equate and recompile your menus. All of the menu commands which reference files will automatically begin to look in the new area. You avoid the need to track down and change each entry individually! You can use Parameter Passing or any other Macro feature within your Equate Directives, as long as you can fit it all on a single line. MACRO NESTING ------------- If you want to get the most power out of your SDL macros you can also include Macros within your Macros. This is called Macro Call Nesting. You can even use Macro Callouts in other Macro definitions or as parameters within Macro Callouts. This ability to incorporate Macros within Macros allows you to effectively double up on your customized "SDL shorthand" as you create new Macros. Macros can be nested in this way up to 25 levels deep. There are some excellent examples of Macro Nesting in your TBBS manual (pages 7-8 and 7-9) and we'll cover this capability in depth in the final installment of this series. We'll take a look at some favorite SDL tricks and tips and generally wrap up all the loose ends then, too. Until then, take time to experiment with Macros. Try using them in your SDL code. Create at least one Macro Definition that includes a Macro Callout within it and we'll check your progress next issue. Part 4: Advanced Techniques --------------------------- We've gained a solid handle on SDL in the first three partsof this articles. In fact, we've covered everything you need to know to create and maintain all of your TBBS menus with SDL. Now we're going take a look at some of SDL's more advanced capabilities. Macro Call Nesting ------------------ Last chapter, we looked briefly at Macro call nesting. Simply put, Macro call nesting is the ability to include SDL Macros within other SDL Macros. This capability can also be used to use Macros as parameters to other Macros. This is a potentially cumulative capability. Macros containing other Macros can be nested inside still other Macros, and so on, up to 25 levels deep. For example, let's create a couple of macros: Macro: Action Type=%1 Key=%2 OptData=%3 Macro: Download 46 Macro: Path C:\TBBS\DOWNLOAD EndMacro: Now let's call out the above Macros, using some as Nested Macro Callouts: @Action(@Download,N,@Path+\FILES /NTL) ... for example, would expand to: Type=46 Key=N OptData=C:\TBBS\DOWNLOAD\FILES /NTL In the above example, the "@Download" and "@Path" Macro callouts, inside the parenthesis, are examples of Nested Macro Callouts being used as parameters to another Macro. Although Macros are traditionally used by most computer software packages to reduce keystrokes, you might have noticed that the Macros in the above example are actually longer, in most cases, than the character strings they invoked. Although the Macros might be longer, in the above example they're still useful to help the TBBS system designer organize the various disk drives, subdirectories and menu option types that might be used in a given TBBS system. It's much easier to remember "@Download," for example, than it is to remember that a Type 46 menu command invokes a Pseudo Download Function. The Include: Directive ---------------------- The Include: Directive is yet another aid to organizing your SDL code. You may have noticed by now that all the SDL code for a complete TBBS system can be incorporated into a single text file. With a large TBBS system, a single SDL source code file can get bulky. The Include: Directive, lets you effectively break up potentially source code files into multiple files, but still call them up for compilation as if they were all part of a single source code file. It's kind of like eating a large meal one bite at a time. That's always easier than trying to dump a whole plate down your throat all at once. To use the Include: Directive, simply type "Include:" followed by the full DOS drive designator, path and, finally the name of the file that you wish to include in your source code. An Include: Directive to insert a source file named MAILMENU.SDL residing in your \MENUS subdirectory might look like this in your main SDL source code: Include: C:\MENUS\MAILMENU.SDL Include: Directive files cannot have Include: Directives in them. Only the original SDL file can have them. But, you can use Include: Directives inside Macros in your original file. Just remember that Include: Directives in Macros won't be executed until those Macros are expanded. The Include: directive is especially useful when you make libraries of macro commands. You can then invoke these standard macros by using the Include: directive in any SDL source file you create. Conditional Compilation ----------------------- Early in this series, we examined SDL's array of compilation options. One advanced SDL compile capability we haven't yet examined is the Conditional compilation. SDL's conditional compilation capabilities allow you to create and maintain several different systems within a single source code file or series of source code files. This capability is especially useful, for example, to computer consultants who might need to manage several different TBBS systems for a number of clients. Consultants who sell turnkey TBBS systems to their clients can use conditional compilation to create a single "basic" source code listing which is capable of creating a multitude of entirely different TBBS systems, depending on the commands given when he or she compiles each system. This capability also allows you to construct complex macros which condition their actions on how many or what types of input parameters they are called with. You could use this capability to offer an option to can Messages in some of your system's message bases, but not in others. The syntax is straightforward. A Conditional Block is entered in an SDL source code listing, opening with either an If: or an IfNot: statement and closed by an Endif: statement. All lines of code appearing between the conditional opening and closing statement are either enacted upon or ignored, depending upon whether they match the opening statement. A conditional block looks like this: If: string1=string2 lines of code which will be compiled if they match the conditional string) Endif: Or... IfNot: string1=string2 . lines of code which will NOT . be compiled if they match the . conditional string) Endif: The If: and IfNot: blocks you've entered into your source code are acted upon when you compile your SDL source code into a TBBS system menu or series of menus. Since If: and IfNot: blocks entered into Macros will not take effect until the Macro is expanded, you can perform two or more tasks with the same Macro. An example is: Macro: Action Key=%1 Type=%2 IfNot: %3= Opt Data=%3 Endif: EndMacro: Note that the second string is absent in the IfNot: statement. This makes the IfNot: test for the presence or absence of the third parameter in the macro. If %3 expands to any text at all, it will fail to match an empty string (nothing) and generate the Opt Data portion of the command. For example: @ACTION(K,11) Would expand to: Key=K Type=11 However, if a third parameter is added to the callout the expansion changes. For example: @ACTION(E,5,EMAIL) Would expand to: Key=E Type=5 Opt Data=EMAIL ANSI and Graphics in TBBS Menus ------------------------------- By far, the one SDL capability most often asked about is the ability to include ANSI and graphics in TBBS menus. This is easier than it at first appears. It is possible to enter graphics display strings in your SDL source code because SDL allows direct entry of control characters and ANSI characters in a source file. This makes the task of designing graphics screens for your TBBS menus a fairly simple one. You simply insert the proper ANSI or graphics characters in your SDL source code in the menu's Title: or Entry: Directive text block. These can be commands to draw something as simple as a box or as complex as a screen drawing of a landscape. Your only real limit is the number of characters that can be included in an Entry: Directive (1000 characters). You can get around this limit by using several Entry: directives with a portion of the text on each one. There are some good examples of such SDL files on the support board for your reference. In either case, just include all of your system's menu commands in whatever ANSI or graphics screen drawing you devise, so they display as part of your drawing. If you were drawing a simple box, a list of that particular menu's available commands should be displayed inside the box. On a landscape, you could run the list of commands across the bottom or top of the screen, or maybe have them appear on a tree trunk, if you're so inclined. Next, set up all of the menu's appropriate Entry: Directives, but don't include a text line for each of the commands that are available on that menu. Skip the text line for each Entry: Directive, setting up each of the menu's available commands without them. Then, your menu will display the graphics menu you've drawn with ANSI codes and NOT the usual ASCII text lines you insert in each Entry:Directive, but each of the menu's defined keys will still work. But, how exactly do you draw with ANSI codes? This is essentially an art and precise instruction is far beyond the scope of an article of this size. The ANSI codes themselves are listed on the last page of the Overview section of your TBBS manual. If you're patient, it's best to enter ANSI graphics codes directly into your SDL source code. A working knowledge of ANSI graphics codes will allow you to create a series of SDL Macros that draw specific lines and boxes that you might want to use regularly and these can then do a lot of the repetitive work for you. Examples of such macros are also available on the TBBS support BBS for downloading. But, there is another way... Many TBBS system designers use a popular ANSI graphics drawing program, such as THEDRAW (available on the eSoft Support BBS). With THEDRAW, you can actually DRAW your graphics on-screen, without having to know the actual ANSI codes that are being used. The program then allows you to SAVE your drawings to an ASCII text file that will contain all the ANSI graphics codes that were used to draw the screen you've created. Once you've drawn your menu screen with a program like THEDRAW, then saved it to disk, you can pull the resulting ANSI code file into your SDL source code with almost any word processor, inserting it right where you want it to display. This method sometimes requires minor additional editing, so an understanding of how ANSI works is still useful, but it's usually not necessary. The only editing you will normally need is to break the ASCII file into sections which are smaller than 1000 characters each and adding the Entry: directive in front of each one. And that's literally everything you need to know to consider yourself an experienced, capable SDL programmer. Like any language, you'll find yourself learning continually as you go, adding to your bag of tricks by trial and error.